datacops-cms
Version:
A modern, extensible CMS built with Next.js and Prisma.
72 lines (64 loc) • 1.86 kB
text/typescript
/* eslint-disable @typescript-eslint/no-explicit-any */
import fs from "fs";
import { NextRequest, NextResponse } from "next/server";
import path from "path";
import { z } from "zod";
const RelationSchema = z.object({
target: z.string(),
relationType: z.enum(["one-one", "one-many", "many-many"]),
});
const FieldSchema = z.object({
name: z.string(),
label: z.string(),
type: z.string(),
required: z.boolean(),
options: z.array(
z.object({
label: z.string(),
value: z.string(),
})
).optional(),
description: z.string().optional(),
relation: RelationSchema.optional(),
slugSource: z.string().optional(),
});
const ContentTypeSchema = z.object({
name: z.string().min(1),
label: z.string().min(1),
fields: z.array(FieldSchema),
});
export async function PUT(
req: NextRequest,
{ params }: { params: { type: string } }
)
{
try {
const data = await req.json();
const parsed = ContentTypeSchema.parse(data);
const safeName = params?.type?.trim()
.replace(/\s+/g, "_")
.replace(/[^a-zA-Z0-9_]/g, "")
.toLowerCase();
const folder = path.resolve(process.cwd(), "content-types");
if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
const filePath = path.join(folder, `${safeName}.json`);
if (!fs.existsSync(filePath)) {
return NextResponse.json(
{ error: "Content type not found" },
{ status: 404 }
);
}
fs.writeFileSync(
filePath,
JSON.stringify({ ...parsed, name: safeName }, null, 2),
"utf-8"
);
return NextResponse.json({
success: true,
message: "Content type updated.",
name: safeName,
});
} catch (e: any) {
return NextResponse.json({ error: e.message }, { status: 400 });
}
}